package wenjun.du.androidart.ipc.aidl

import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_aidl.*
import wenjun.du.androidart.R
import wenjun.du.androidart.ipc.Book
import wenjun.du.androidart.ipc.BookChangeListener
import wenjun.du.androidart.ipc.BookOperation

/**
 * <1> 使用aidl的方式 实现跨进程通讯
 * 1.绑定服务
 * 2.服务端实现binder类的接口 返回给客户端
 * 3.客户端拿到服务端返回的binder 创建binder的代理类 调用服务端方法
 * 主要客户端和服务端调用服务的线程问题 服务端在binder子线程中调用 客户端则会阻塞调用线程
 *
 * <2> 同时绑定成功的接口类 同样可以传递aidl对象 用于服务端调用客户端方法
 * 客户端的代码对象把aidl对象传递到服务端的过程中 会把aidl对象转换一次 生成新的对象
 *
 * <3> 监听服务是否存在
 *  1. 给客户的binder设置binderDied监听
 *  2. 在绑定服务中监听服务断链
 *
 *  <4> 绑定服务的权限设置
 *
 * */
class AidlActivity : AppCompatActivity() {
    companion object {
        private const val TAG = "AidlActivity"
    }

    private lateinit var mConnect: ServiceConnection
    private lateinit var mBinder: BookOperation

    private val mListener: BookChangeListener = object : BookChangeListener.Stub() {
        override fun bookChange(book: Book?) {
            Log.d(TAG, "bookChange: book add success ${book?.Name}")
        }
    }

    private lateinit var binderDiedListener: IBinder.DeathRecipient
    init {
        binderDiedListener = IBinder.DeathRecipient {
            Log.d(TAG, "binder died ====== todo 重新连接: ")
            binderService()
            mBinder.asBinder().unlinkToDeath(binderDiedListener, 0)
        }
    }



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_aidl)

        mConnect = object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                if (service != null) {
                    mBinder = BookOperation.Stub.asInterface(service)
                    mBinder.asBinder().linkToDeath(binderDiedListener, 0)
                    mBinder.registerenListener(mListener) //binder对象反序列化传递到服务端 生成另外一个对象
                }
            }

            override fun onServiceDisconnected(name: ComponentName?) {
                Log.d(TAG, "onServiceDisconnected: ===== ")
//                binderService()
            }
        }
        binderService()


        get_book.setOnClickListener {
            if (::mBinder.isInitialized) {
                for (book in mBinder.book) {
                    Log.d(TAG, "onCreate: get book name ${book.Name} price ${book.price}")
                }
            }
        }

        set_book.setOnClickListener {
            if (::mBinder.isInitialized) {
                val book = Book("android开发艺术", 30)
                mBinder.addBooks(book)
            }
        }
    }

    private fun binderService() {
        val intent = Intent(this, AidlService::class.java)
        bindService(intent, mConnect, BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        unbindService(mConnect)
        mBinder.unRegisterenListener(mListener)
    }
}